/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.hiruss.imageprocessor.ui;

import com.hiruss.imageprocessor.util.ImageHandler;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;

/**
 *
 * @author Hiru
 */
public class ImageFrame extends JComponent implements MouseMotionListener, MouseListener {

    public static final int DEFAULT_HEIGHT = 360;
    public static final int DEFAULT_WIDTH = 360;
    public static final int MIN_HEIGHT = 120;
    public static final int MIN_WIDTH = 120;
    public static final int BORDER_WIDTH = 6;
    public static final int TOP_BORDER_WIDTH = 24;
    public static final int RESIZE_ICON_WIDTH = 64;
    private int x = 30, y = 30, width = DEFAULT_WIDTH, height = DEFAULT_HEIGHT;
    private JLabel resizeIcon = new JLabel(
            new javax.swing.ImageIcon(getClass().getResource("/com/hiruss/imageprocessor/ui/images/resize - large.png")));
    private BufferedImage image;
    private Image scaledImage;
    private int dragX = 0, dragY = 0;

    public ImageFrame(BufferedImage image, String title) {
        addMouseMotionListener(this);
        addMouseListener(this);
        setLayout(null);
//        setToolTipText("Move");
        Border raisedbevel = BorderFactory.createRaisedBevelBorder();
        Border loweredbevel = BorderFactory.createLoweredBevelBorder();
        Border matteBorder = BorderFactory.createMatteBorder(TOP_BORDER_WIDTH, BORDER_WIDTH, BORDER_WIDTH, BORDER_WIDTH, Color.LIGHT_GRAY);
        Border compoundBorder = BorderFactory.createCompoundBorder(matteBorder, loweredbevel);
        compoundBorder = BorderFactory.createCompoundBorder(raisedbevel, compoundBorder);
        if (title != null) {
            Font font = new java.awt.Font("Times New Roman", 1, 12);
            compoundBorder = BorderFactory.createTitledBorder(compoundBorder, title, TitledBorder.CENTER, TitledBorder.DEFAULT_POSITION,
                    font, Color.BLACK);
        }
        setBorder(compoundBorder);
        setCursor(new java.awt.Cursor(java.awt.Cursor.MOVE_CURSOR));
//        resizeIcon.setToolTipText("Re-size Window");
        resizeIcon.setCursor(new java.awt.Cursor(java.awt.Cursor.SE_RESIZE_CURSOR));
        resizeIcon.addMouseMotionListener(this);
        add(resizeIcon);
        resizeIcon.setBounds(this.width - RESIZE_ICON_WIDTH, this.height - RESIZE_ICON_WIDTH,
                RESIZE_ICON_WIDTH, RESIZE_ICON_WIDTH);
        setComponentZOrder(resizeIcon, 0);
        this.image = image;
        update();
    }

    private void update() {
        double imgWidth = this.image.getWidth();
        double imgHeight = this.image.getHeight();
        double ratio = Math.max(imgWidth / this.width, imgHeight / this.height);
        this.width = (int) (imgWidth / ratio);
        this.height = (int) (imgHeight / ratio);
        scaledImage = ImageHandler.scale(image, this.width, this.height, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        super.setBounds(this.x, this.y, this.width + BORDER_WIDTH * 2, this.height + BORDER_WIDTH + TOP_BORDER_WIDTH);
        resizeIcon.setBounds(this.width + BORDER_WIDTH - RESIZE_ICON_WIDTH, this.height + TOP_BORDER_WIDTH - RESIZE_ICON_WIDTH,
                RESIZE_ICON_WIDTH, RESIZE_ICON_WIDTH);
        repaint();
    }

    public void updateImage(BufferedImage image) {
        this.image = image;
        update();
    }

    public final void setFrameSize(int width, int height) {
        this.width = width;
        this.height = height;
        update();
    }

    public void setPosition(int x, int y) {
        this.x = x;
        this.y = y;
        super.setBounds(this.x, this.y, this.width + BORDER_WIDTH * 2, this.height + BORDER_WIDTH + TOP_BORDER_WIDTH);
    }

    public int getFrameWidth() {
        return this.width;
    }

    public int getFrameHeight() {
        return this.height;
    }

    @Override
    public void paint(Graphics g) {
        if (this.scaledImage != null) {
            Graphics2D g2 = (Graphics2D) g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2.drawImage(scaledImage, BORDER_WIDTH, TOP_BORDER_WIDTH, this);
        }
        super.paint(g);
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        if (resizeIcon.equals(e.getComponent())) {
            setFrameSize(
                    Math.max(MIN_WIDTH, resizeIcon.getX() + e.getX()),
                    Math.max(MIN_HEIGHT, resizeIcon.getY() + e.getY()));
        } else {
            setPosition(getX() - dragX + e.getX(), getY() - dragY + e.getY());
        }
    }

    @Override
    public void mouseMoved(MouseEvent e) {
    }

    @Override
    public void mouseClicked(MouseEvent e) {        
    }

    @Override
    public void mousePressed(MouseEvent e) {
        this.dragX = e.getX();
        this.dragY = e.getY();
        getParent().setComponentZOrder(this, 0);
        getParent().repaint();
    }

    @Override
    public void mouseReleased(MouseEvent e) {
    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

    @Override
    public void mouseExited(MouseEvent e) {
    }
}
